module ApplicationHelper
  
  def do_menu
    menu = Menu.root self
               
    menu.home.my_proposals :path => proposals_path, :highlight_mappings => "^#{proposals_path}.*$"
    menu.home.new_proposal :path => new_proposal_path
    
    menu.administration.jurisdictions
    menu.administration.roles
    menu.administration.jurisdiction_members
    menu.administration.users
    
    menu.settings.preferences :path => ""

    menu.show    
  end
  
  class Menu
    
    def self.root template
      return Menu.new nil, :root, template
    end
    
    def initialize args, method, parent
      @args = args ? args : Hash.new
      @method = method
      @parent = parent          
      @items = {}
    end
    
    def template
      (@parent.kind_of? Menu) ? @parent.template : @parent
    end
    
    def level count = 0
      (@parent.kind_of? Menu) ? @parent.level(count + 1) : count
    end

    def for_arg arg
      val = @args[arg] 
      if !val then val = yield end
      val  
    end

    def show_line t
      if @method == :root then return "" end 
      
      label = "" << (for_arg :label do @method.to_s.gsub(/[_]/, " ").capitalize end)
      is_header = (for_arg :header do @items.size > 0 end)
      path = is_header ? "" : (for_arg :path do t.send("#{@method.to_s}_path") end)
      cssclass = is_header ? "menuitem menuheader" : "menuitem menuchild"
      
      link = is_header ? label : t.content_tag(:a, label.html_safe, {:href => path})
      
      line = t.content_tag(:td, link)
      level.times do line = t.content_tag(:td, "", {:width => "10px"}) + line end
      line = t.content_tag(:table, t.content_tag(:tbody, t.content_tag(:tr, line, {:class => cssclass})), {:class => "menutable"})
      
      highlight_mappings = for_arg :highlight_mappings do nil end
      if highlight_mappings
        highlight_mappings_script = ""
        highlight_mappings = [highlight_mappings] if highlight_mappings.kind_of? String
        highlight_mappings.each do |item|
          highlight_mappings_script << "addHighlightMappings(\"#{item}\", \"#{path}\");"  
        end
        line << t.javascript_tag(highlight_mappings_script)
      end
      line
    end

    def show
      t = template

      html = show_line t

      @items.keys.each do |key|        
        html << @items[key].show
      end
      
      html.html_safe
    end
    
    def method_missing m, *args
      if !@items[m]
        @items[m] = Menu.new args[0], m, self
      end
      @items[m]
    end
  end

  def enrich_args_by_css_class index, css_class, *args
    if args[index] == nil
      args[index] = {}
    end
    args[index][:class] = css_class
    args
  end

  def labeled_sorted_zebratable_for title, *args, &block
    labeled_table_for title do sorted_zebratable_for(*args, &block) end
  end

  def labeled_zebratable_for title, *args, &block
    labeled_table_for title do zebratable_for(*args, &block) end
  end

  def labeled_table_for title
    header = content_tag(:thead, content_tag(:tr, content_tag(:th, title)))
    body = content_tag(:tbody, content_tag(:tr, content_tag(:td, yield)))
    content_tag(:table, header << body, :class => "zebratableLabeled") 
  end

  def sorted_zebratable_for *args, &block
    table_for *enrich_args_by_css_class(2, "sorted zebratable", *args), &block
  end

  def zebratable_for *args, &block    
    table_for *enrich_args_by_css_class(2, "zebratable", *args), &block
  end

  def table_for models, titles, options = nil, &block
    header = "".html_safe
    titles.each do |h|
      header << content_tag(:th, h.to_s.gsub(/[_]/, " ").capitalize)
    end
    body = "".html_safe
    models.each do |model|
      sub_body = capture(model, &block)
      if sub_body.length > 0
        if sub_body =~ /.*<tr.*/
          body << sub_body 
        else
          body << content_tag(:tr, sub_body)
        end
      end
    end
    content_tag(:table, content_tag(:thead, content_tag(:tr, header)) << content_tag(:tbody, body), options)
  end
  
  def cells_for *args
    cells = "".html_safe
    args.each do |td|
      cells << content_tag(:td, td)
    end
    cells
  end
  
  def master_group_box title = "Title", &block
    group_box title, :class => "zebratable", :width => "100%", :cellpadding => "3px", &block
  end
  
  def zebra_group_box *args, &block
    group_box *enrich_args_by_css_class(1, "zebratable", *args), &block
  end
  
  def group_box title = "Title", options = nil, &block
    content_tag(:table, content_tag(:thead, content_tag(:tr, content_tag(:th, title))) + content_tag(:tbody, content_tag(:tr, content_tag(:td, capture(&block)))), options)
  end

end